package com.cennavi.bigdata.baotou.scripts;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import org.apache.log4j.Logger;
import sun.misc.BASE64Decoder;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * Created by zuoweiguang on 2016/11/4.
 */
public class ActualTimeTraffic_1 extends ActualTimeRequest {

    private Logger logger = Logger.getLogger(ActualTimeTraffic_1.class);
    private DBCollection trafficStatusCol;

    public void refrashTraffic() {

        int rticCount = 0;
        int rticTotal = 0;
        try {
            String url = propObj.getString("RticTraffic");
            String result = sendGet(url);

            trafficStatusCol = getMongoCollection("traffic_status");

            JSONObject resultObj = JSONObject.parseObject(result);
            JSONObject resultValue = resultObj.getJSONObject("result");
            JSONObject city = resultValue.getJSONObject("cities").getJSONObject("city");
            String adcode = city.getString("adcode");
            String updatetime = city.getString("updatetime");
            String version = city.getString("version");
            JSONArray meshList = city.getJSONArray("mesh");
            System.out.println("adcode:" + adcode + ", updatetime:" + updatetime + ", version:" + version);
            System.out.println("rtic http get size:" + meshList.size());


            Iterator<Object> it = meshList.iterator();
            while (it.hasNext()) {
                JSONObject obj = (JSONObject) it.next();
                String code = obj.getString("code");
                String flow = obj.getString("flow");
                if (flow == null) {
                    continue;
                }
                byte[] data = this.decodeBase64(flow);
                List<JSONObject> flowJsonList = this.praseData(data);

                for (JSONObject flowJson : flowJsonList) {
                    int meshCodeInt = flowJson.getInteger("meshCode");
                    String rticIdStr = flowJson.getString("rticId");
                    int rticLinkKindInt = flowJson.getInteger("rticKind");
                    int travelTime = flowJson.getInteger("travelTime");
                    int iLOS = flowJson.getInteger("iLOS");
                    //分段拥堵值
                    List<JSONObject> sectionCntList = (List) flowJson.get("sectionCntList");

                    //到correspondingOfzhuhai对照表中查询对应link_id
                    BasicDBObject query = new BasicDBObject();
                    query.append("mesh_code", meshCodeInt);
                    query.append("rtic_id", rticIdStr);
                    query.append("rtic_link_kind", rticLinkKindInt);

                    DBObject rtic_info = trafficStatusCol.findOne(query);
                    if (rtic_info != null) {
                        int old_status = (Integer) rtic_info.get("status");

                        DBObject trafficObj = new BasicDBObject();
                        trafficObj.put("status", iLOS);
                        trafficObj.put("temp_status", old_status);
                        trafficObj.put("traveltime", travelTime);
                        trafficObj.put("updatetime", sdf.format(new Date()));
                        trafficObj.put("rtic_updatetime", updatetime);
                        trafficObj.put("sectionCntList", sectionCntList);

                        //更新当前link路况到mongo
                        trafficStatusCol.update(query, new BasicDBObject("$set", trafficObj), false, true);
                        rticCount += 1;
                        rticTotal += 1;
                        if (rticCount % 2000 == 0) {
                            System.out.println("refrash rtic count:" + rticCount);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeMongo();
            System.out.println("refrash rtic total:" + rticTotal);
        }
    }

    private byte[] decodeBase64(String str) {
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] result = null;
        try {
            result = decoder.decodeBuffer(str);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    private List<JSONObject> praseData(byte[] meshData) {
        List<JSONObject> flowJsonlist = new ArrayList<>();
        int i = 0;
        // 计算2次网格号，JamNew中格网号占3个字节
        int x1 = (((meshData[i + 2] & 0xF0) << 1) | (meshData[i] & 0xF8) >> 3);
        int y1 = (((meshData[i + 2] & 0xF) << 5) | (meshData[i + 1] & 0xF8) >> 3);
        int x2 = ((meshData[i] & 0x7) & 0xFF);
        int y2 = ((meshData[i + 1] & 0x7) & 0xFF);
        int meshCode = y1 * 10000 + x1 * 100 + y2 * 10 + x2;
        i += 3;
        // RTIC记录数
        int rticCnt = (((meshData[i] & 0xFF) << 8) | ((meshData[i + 1] & 0xFF)));
        i += 2;
        // 路况信息
        for (int j = 0; j < rticCnt; j++) {
            JSONObject flowJson = new JSONObject();
            // 路链分类
            int rticKind = ((meshData[i] & 0xF0) >> 4) + 1;
            // 路链序号
            String rticSeqId = String.valueOf((meshData[i] & 0x0F) << 8 | (meshData[i + 1] & 0xFF));
            while (rticSeqId.length() != 4) {
                rticSeqId = "0" + rticSeqId;
            }
            String rticId = meshCode + "" + rticKind + "" + rticSeqId;
            flowJson.put("rticId", rticId);
            flowJson.put("meshCode", meshCode);
            flowJson.put("rticKind", rticKind);
            flowJson.put("rticSeqId", rticSeqId);
            i += 2;

            // 路链旅行时间
            int travelTime = (meshData[i] & 0xFF) << 8 | (meshData[i + 1] & 0xFF);
            flowJson.put("travelTime", travelTime);
            i += 2;
            // 拥堵路段数
            int sectionCnt = meshData[i] & 0xFF;
            i += 1;
            // 拥堵程度
            int iLOS = (meshData[i] & 0x18) >> 3;
            flowJson.put("iLOS", iLOS);
            flowJson.put("sectionCnt", sectionCnt);

            // 旅行时间有无
            int travelTimeFlag = (meshData[i] & 0x4) >> 2;
            // 旅行时间类别
            int travelTimeKind = (meshData[i] & 0x2) >> 1;
            i += 1;
            // 拥堵分段
            List<JSONObject> sectionCntList = new ArrayList<>();
            for (int k = 0; k < sectionCnt; k++) {
                JSONObject sectionCntJson = new JSONObject();
                /** 分段拥堵程度 */
                int splitILOS = (meshData[i] & 0xC0) >> 6 & 0xFF;
                // 拥堵路段终点与路链终点的距离
                int startLen = ((meshData[i] & 0x3F) << 8 | (meshData[i + 1] & 0xFF));// 注意:RJamNew里面长度单位是10米
                i += 2;
                // 拥堵路段的拥堵长度
                int degreeLen = ((meshData[i] & 0xFF) << 8 | (meshData[i + 1] & 0xFF));// 注意:RJamNew里面长度单位是10米
                i += 2;
                sectionCntJson.put("SplitILOS", splitILOS);
                sectionCntJson.put("startLen", startLen);
                sectionCntJson.put("degreeLen", degreeLen);
                sectionCntList.add(sectionCntJson);
            } // end for k
            flowJson.put("sectionCntList", sectionCntList);
            flowJsonlist.add(flowJson);
        } // end for j
        return flowJsonlist;
    }

    public static void main(String[] args) {
        new ActualTimeTraffic_1().refrashTraffic();
    }

}

